#include "ui_compositeordermanageredit.h"
#include "compositeordermanageredit.h"
#include "compositeordermanagerutil.h"

#include "imodule.h"
#include "dragview.h"
#include "treemodel.h"

#include <cadinterface.h>
#include <ioselectdialog.h>
#include <sqltool.h>
#include <QVector3D>
#include <QMessageBox>


struct CompositeOrderManagerEditPrivate {
    QMap<QString, QVariantMap> lams;
    QMap<QString, QList<QVariantMap>> plyLams;
    TreeModel* treeModel;
    QMap<QString, QString> mappingData2Tree;

    QMap<QString, QVariantMap> mapMatColors;

    CompositeOrderManagerEditPrivate() {

        Sqltool::instance().changeInfoDb();

        auto tmplams = Sqltool::instance().selectAllByTableName(compositeOrderManagerUtil::lamTableName);
        for (const auto& lam : tmplams) {
            if (!lam.contains("Name")) continue;
            const auto& p = lam.value("Name").toString();
            if (p.isEmpty()) continue;
            lams[p] = lam;
        }

        auto plys =Sqltool::instance().selectAllByTableName(compositeOrderManagerUtil::plyTableName);
        // Parent
        for (const auto& ply : plys) {
            if (!ply.contains("Parent")) continue;
            const auto& p = ply.value("Parent").toString();
            if (p.isEmpty()) continue;
            auto mat = ply.value("Material").toString();
            if (!mat.isEmpty())
                mapMatColors[mat] = {};
            plyLams[p].append(ply);
        }

        Sqltool::instance().changeMaterialDb();
        for (const auto& key : mapMatColors.keys()) {
            mapMatColors[key] = Sqltool::instance().selectOne("Material", {"Specification", key});
        }


        QStringList headers = {
            "Object Type",
            "Object Name",
            "Parent",
            "Sequence",
            "Step",
            "Specified Orientation",
            "Material",
            "Drop-Off Order",
            "Zones"
        };
        treeModel = new TreeModel(headers);


        mappingData2Tree = {{"Object Type", "ObjectType"},
            {"Object Name", "Name"},
            {"Parent", "Parent"},
            {"Sequence", "Sequence"},
            {"Step", "Step"},
            {"Specified Orientation","SpecifiedOrientation"},
            {"Material","Material"},
            {"Drop-Off Order","DropOffOrderPreSorting"},
            {"Zones","Zones"},};
    }

};

CompositeOrderManagerEdit::CompositeOrderManagerEdit(QWidget *parent) :
    IoEditFrameInterface(parent),
    ui(new Ui::CompositeOrderManagerEdit)
{
    ui->setupUi(this);

    m_d = new CompositeOrderManagerEditPrivate;
    ui->treeView->setTreeModel(m_d->treeModel);
    m_d->treeModel->setCallback([this]()->int {
        return ui->lineEdit_StepInc->text().toInt();
    });
    m_d->treeModel->setParent(ui->treeView);

    ui->comboBox_laminate->addItems(m_d->lams.keys());
    ui->comboBox_laminate->setCurrentIndex(0);
    connect(ui->comboBox_laminate, &QComboBox::currentTextChanged, this, [this](const QString& text){
        changeLam(text);
    });
    if (m_d->lams.size() > 0)
        changeLam(ui->comboBox_laminate->currentText() , false);


    connect(ui->pbtn_delete, &QPushButton::clicked, this, &CompositeOrderManagerEdit::deleteItems);




}

CompositeOrderManagerEdit::~CompositeOrderManagerEdit()
{
    delete m_d;
    delete ui;
}

QString CompositeOrderManagerEdit::title()
{
    return "Composite Order Manager";
}

void CompositeOrderManagerEdit::reInitUI()
{

}

void CompositeOrderManagerEdit::editUI(const QString &name)
{

}

bool CompositeOrderManagerEdit::save()
{
    auto rootNode = m_d->treeModel->treeData();
    auto lamNode = rootNode.children[0];
    auto plyNodes = lamNode.children;
    QString lamName = lamNode.data["Object Name"].toString();
    auto& oldPlys = m_d->plyLams[lamName];
    QList<QPair<QVariantMap, QVariantMap>> updateList;
    for (const auto& plyNode : plyNodes) {
        auto plyName = plyNode.data["Object Name"].toString();
        QVariantMap ct{{"Name", plyName}};
        QVariantMap upPly;
        for (auto& ply : oldPlys) {
            if (ply["Name"].toString() == plyName) {
                for (auto it = m_d->mappingData2Tree.begin(); it != m_d->mappingData2Tree.end();++it) {
                    if (ply.contains(*it))
                        ply[*it] = plyNode.data[it.key()];
                }
                upPly = ply;
                break;
            }
        }
        updateList.append({upPly, ct});

    }
    Sqltool::instance().changeInfoDb();
    Sqltool::instance().updateBatchDb(compositeOrderManagerUtil::plyTableName, updateList);

    return true;
}

bool CompositeOrderManagerEdit::update()  {
    return true;
}

void CompositeOrderManagerEdit::createBaseOn(const QString& name) {

}

void CompositeOrderManagerEdit::changeLam(const QString &text, bool needSave)
{
    if (text.isEmpty()) return;
    bool isChanged = m_d->treeModel->isChanged();
    if (needSave && isChanged) {
        auto reply = QMessageBox::question(this,
                                           "确认保存",
                                           "当前界面有未保存的数据是否保存？",
                                           QMessageBox::Yes | QMessageBox::No);

        if (reply == QMessageBox::Yes) {
            qDebug() << "用户保存";
            CompositeOrderManagerEdit::save();
        }
    }

    if (!m_d->lams.contains(text)) return;
    const auto& lam = m_d->lams[text];
    Node rootNode;
    Node lamNode;
    for (auto it = m_d->mappingData2Tree.begin(); it != m_d->mappingData2Tree.end();++it) {
        QString tmpValue = "";
        if (it.key() == "Object Type")
            tmpValue = "Laminate";
        lamNode.data[it.key()] = lam.value(*it, tmpValue);
    }

    QMap<QString, QColor> toColor{{"Red", Qt::red},
                                  {"Blue", Qt::blue},
                                  {"Green", Qt::green},
                                  {"Yellow", Qt::yellow}};
    QMap<QString, QString> toMatKey{{"0", "Color_0_Degrees"},
                                    {"45", "Color_45_Degrees"},
                                    {"-45", "Color_np45_Degrees"},
                                    {"90", "Color_90_Degrees"},
                                    {"0/90", "Color_090_Degrees"},
                                    {"+/-45", "Color_Other_Degrees"}};

    const auto& plys = m_d->plyLams[text];
    
    // 创建临时列表用于排序
    QList<Node> plyNodes;
    for (const auto& ply : plys) {
        Node plyNode;
        for (auto it = m_d->mappingData2Tree.begin(); it != m_d->mappingData2Tree.end();++it) {
            QString tmpValue = "";
            if (it.key() == "Object Type")
                tmpValue = "Ply";
            plyNode.data[it.key()] = ply.value(*it, tmpValue);
        }

        //color
        const auto sp = ply["SpecifiedOrientation"].toString();
        const auto matName = ply["Material"].toString();
        plyNode.data["color"] = QVariant::fromValue(QColor(Qt::white));
        if (!sp.isEmpty() && !matName.isEmpty()) {
            auto mat = m_d->mapMatColors[matName];
            auto key = toMatKey[sp];
            auto value = mat[key].toString();
            if (toColor.contains(value))
                plyNode.data["color"] = QVariant::fromValue(toColor[value]);
        }
        plyNodes.append(plyNode);
    }

    // 按照Sequence和step排序
    std::sort(plyNodes.begin(), plyNodes.end(), [](const Node& a, const Node& b) {
        QString sequenceA = a.data["Sequence"].toString();
        QString sequenceB = b.data["Sequence"].toString();
        
        // 首先按照Sequence排序
        if (sequenceA != sequenceB) {
            return sequenceA < sequenceB;
        }
        
        // 相同Sequence时按照step排序
        QString stepA = a.data["Step"].toString();
        QString stepB = b.data["Step"].toString();
        return stepA.toDouble() < stepB.toDouble();
    });

    // 将排序后的节点添加到lamNode
    for (const auto& plyNode : plyNodes) {
        lamNode.children.append(plyNode);
    }
    
    rootNode.children.append(lamNode);
    m_d->treeModel->setTreeData(rootNode);
}

void CompositeOrderManagerEdit::deleteItems()
{
    auto indexs = ui->treeView->selectionModel()->selectedIndexes();

    QSet<int> rows;
    for (const auto& idx : indexs) {
        if (idx.isValid() && idx.internalId() > 0) {
            rows.insert(idx.internalId() - 1);
        }
    }

    if (rows.isEmpty()) {
        QMessageBox::information(this, "提示", "请选择要删除的Ply节点");
        return;
    }

    // 获取当前Laminate名称
    auto rootNode = m_d->treeModel->treeData();
    QString lamName = rootNode.children[0].data["Object Name"].toString();

    // 从TreeModel中删除

    auto& plyNodes = rootNode.children[0].children;

    // 按倒序删除以避免索引变化
    QList<int> sortedRows = rows.values();
    std::sort(sortedRows.begin(), sortedRows.end(), std::greater<int>());
    auto& plyList = m_d->plyLams[lamName];
    QMultiMap<QString, QVariant> delItems;
    for (int row : sortedRows) {
        if (row >= 0 && row < plyNodes.size()) {
            // 获取要删除的Ply名称
            QString plyName = plyNodes[row].data["Object Name"].toString();
            // 从plyLams中删除对应数据
            for (int i = 0; i < plyList.size(); ++i) {
                if (plyList[i]["Name"].toString() == plyName) {
                    plyList.removeAt(i);
                    delItems.insert("Name", plyName);
                    break;
                }
            }

            // 从TreeModel中删除
            plyNodes.remove(row);
        }
    }
    Sqltool::instance().changeInfoDb();
    Sqltool::instance().deleteItemsByConditions(compositeOrderManagerUtil::plyTableName, delItems);


    m_d->treeModel->setTreeData(rootNode);
}
